#ifndef CONFIG_H
#define CONFIG_H

#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include "boost/property_tree/xml_parser.hpp"
#include "boost/property_tree/json_parser.hpp"
#include <boost/property_tree/ini_parser.hpp>
#include <boost/system/system_error.hpp>

#include <iostream>

namespace Fast {

enum FILE_FORMAT{
    T_JSON = 0,
    T_INI ,
    T_XML,
    T_INFO,
    T_NO_FORMAT,
    T_ALL
};

static FILE_FORMAT GetIndex(std::string ext){
    if("json" == ext){
        return  T_JSON;
    }else if ("info" == ext|| "config" == ext|| "sys" == ext) {
        return   T_INFO;
    }else if ("xml" == ext) {
        return   T_XML;
    }else if ("ini" == ext) {
        return   T_INI;
    }else {
        return   T_NO_FORMAT;
    }
}

using namespace boost::property_tree;



class config
{
public:
    config(std::string str,std::string ext);
    config(const std::string &fn);  // 使用文件
    config(std::string_view str,const char* ext);

    // void getUsage();
    void sync();



    // 格式分离,获取文件格式
    std::string SplitFilename (const std::string& str)
    {
        std::string::size_type pos=str.rfind('.');
        std::string ext=str.substr(pos==std::string::npos?str.length():pos+1);
        return ext;
    }

    void putStr(const std::string str,const std::string ext);

    template<typename T>
    T get(const std::string &index) const{
        T ret ;
        try {
            ret = pt.get<T>(index);
        } catch (const boost::exception &e) {
            std::cout<<"Error Read!"<<std::endl;

        }catch(const boost::system::system_error &e){
            std::cout <<"system:"<< e.what() << std::endl ;
        }
        return ret;
    }

    template<typename T>
    bool put(const std::string &index,T value) const{
        bool ret = true;
        try {
            pt.put<T>(index,value);
        } catch (const boost::exception &e) {
            ret = false;
            std::cout<<"Error Read!"<<std::endl;

        }catch(const boost::system::system_error &e){
            std::cout <<"system:"<< e.what() << std::endl ;
            ret = false;
        }

        return ret;
    }

    void write2File();                  // 写文件
    boost::property_tree::ptree getChild(std::string key,int index){
        int in = 0;
        auto child = pt.get_child(key);
        boost::property_tree::ptree ret;
        for (boost::property_tree::ptree::iterator it = child.begin(); it != child.end(); ++it){
            if(index == in)
                ret = it->second;
            in++;
        }
        return ret;
    }

private:
    void write2File(std::string m_path);                  // 写文件
    void import(std::string data);      // 自动导入
    void import(std::stringstream &data);      // 自动导入
    std::ostringstream write2OS();

private:
    bool isFile = false;
    std::string path;
    boost::property_tree::ptree pt;
    FILE_FORMAT ext_format;

};



}



#endif // CONFIG_H
